package org.example.java.util.concurrency.advanced_object;

/**
 * 信号量
 * Created by Juntao.Zhang on 2014/9/11.
 */

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreTest {
  public static void main(String[] args) {
    // 线程池
    final ExecutorService exec = Executors.newCachedThreadPool();
    // 只能5个线程同时访问
    final Semaphore semp = new Semaphore(5);
    System.out.println("before availablePermits:" + semp.availablePermits());
    // 模拟10个客户端访问
    final Object lock1 = new Object();
    final Object lock2 = new Object();
    for (int index = 0; index < 10; index++) {
      final Integer NO = index;
      final Runnable run = new Runnable() {
        public void run() {
          try {
            // 获取许可  //从此信号量获取一个许可，在提供一个许可前一直将线程阻塞，否则线程被中断。
            synchronized (lock1) {
              System.out.printf("Accessing: %s acquiring ,availablePermits:%s %n", NO, semp.availablePermits());
              semp.acquire();
              System.out.printf("Accessing: %s acquired ,availablePermits:%s%n", NO, semp.availablePermits());
            }
            Thread.sleep((long) (Math.random() * 1000));
            // 访问完后，释放
            synchronized (lock2) {
              System.out.printf("Access: %s release before ,availablePermits:%s %n", NO, semp.availablePermits());
              semp.release();
              System.out.printf("Access: %s release after ,availablePermits:%s %n", NO, semp.availablePermits());
//              System.out.printf("Access: %s release after ,drainPermits:%s %n", NO, semp.drainPermits());//获取并返回立即可用的所有许可。
            }
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      };
      exec.execute(run);
    }
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("after availablePermits:" + semp.availablePermits());
    // 退出线程池
    exec.shutdown();

  }
}